/* eslint-disable no-console */
import type { IPublicTypeProjectSchema, ResultDir } from '@alilc/lowcode-types';
import createCustomBuilder from '../customSolution';

interface FlattenFile {
  /**
   * 文件路径
   */
  pathName: string;

  /**
   * 文件内容
   */
  content: string | Buffer;
}

function joinPath(...pathParts: string[]): string {
  return pathParts
    .filter((x) => x !== '' && x !== '.')
    .join('/')
    .replace(/\\+/g, '/')
    .replace(/\/+/g, '/');
}

function flattenResult(dir: ResultDir, cwd = ''): FlattenFile[] {
  if (!dir.files.length && !dir.dirs.length) {
    return [];
  }

  return [
    ...dir.files.map(
      (file): FlattenFile => ({
        pathName: joinPath(cwd, `${file.name}${file.ext ? `.${file.ext}` : ''}`),
        content: file.content,
      }),
    ),
  ].concat(...dir.dirs.map((subDir) => flattenResult(subDir, joinPath(cwd, subDir.name))));
}

async function run(msg: { solution: string; schema: IPublicTypeProjectSchema; flattenResult?: boolean }) {
  try {
    print('begin run...');
    const { solution } = msg;
    if (!solution) {
      throw new Error('solution is required');
    }

    const createAppBuilder = createCustomBuilder;
    if (typeof createAppBuilder !== 'function') {
      throw new Error(`solution '${solution}' is invalid`);
    }

    const appBuilder = createAppBuilder();

    print('generating from schema: %o', msg.schema);

    const result = await appBuilder.generateProject(msg.schema);

    print('generated result: %o', result);

    const finalResult = msg.flattenResult
      ? flattenResult(result)
      : result;

    if (msg.flattenResult) {
      print('flatten result: %o', finalResult);
    }
   return finalResult;
  } catch (e) {
    printErr(`${e}`);
  }
}

function print(text: string, ...args: any[]) {
  console.log(`[code-generator/worker]: ${text}`, ...args);
}

function printErr(text: string, ...args: any[]) {
  console.error(`[code-generator/worker]: %c${text}`, 'color:red', ...args);
}

export default {
  run
}